﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using ESSManageService.Common.Helper;
using ESSManageService.Model.DBModels.Info;
using Microsoft.Data.SqlClient;
using Newtonsoft.Json;
using SqlSugar;

namespace ESSManageService.Common
{
    public class DBSeed
    {
        private static string SeedDataFolder = "ESSManage.Data.json/{0}.tsv";

        /// <summary>
        /// 异步添加种子数据
        /// </summary>
        /// <param name="myContext"></param>
        /// <param name="WebRootPath"></param>
        /// <returns></returns>
        public static async Task SeedAsync(MyContext myContext)
        {
            try
            {
                ConsoleHelper.WriteInfoLine("************ ESSManageService 检查数据库 *****************");
                ConsoleHelper.WriteInfoLine($"Master DB ConnectString: {myContext.Db.CurrentConnectionConfig.ConnectionString}");

                if (AppSettings.app(new string[] { "AppSettings", "SeedDBBaseEnabled" }).ObjToBool()) 
                {
                    //检查数据库是否存在，如果不存在则创建
                    var databaseName = "ESSManageService";
                    //var databaseList = myContext.Db.DbMaintenance.GetDataBaseList();
                    ConsoleHelper.WriteWarningLine($"，正在创建数据库...!");
                    // 创建数据库
                    myContext.Db.DbMaintenance.CreateDatabase(databaseName);
                    ConsoleHelper.WriteSuccessLine($"Database created successfully!");

                    //初始化表结构
                    if (AppSettings.app(new string[] { "AppSettings", "SeedDBEnabled" }).ObjToBool())
                    {
                        // 创建数据库表，遍历指定命名空间下的class，
                        // 注意不要把其他命名空间下的也添加进来。

                        ConsoleHelper.WriteInfoLine("Create Tables...");

                        var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
                        var referencedAssemblies = System.IO.Directory.GetFiles(path, "ESSManageService.Model.dll")
                           .Select(Assembly.LoadFrom).ToArray();
                        var modelTypes = referencedAssemblies
                           .SelectMany(a => a.DefinedTypes)
                           .Select(type => type.AsType())
                           .Where(x => x.IsClass && x.Namespace is "ESSManageService.Model.DBModels.Info")
                           .ToList();
                        modelTypes.ForEach(t =>
                        {
                            //表不存在，则创建表
                            if (!myContext.Db.DbMaintenance.IsAnyTable(t.Name))
                            {
                                Console.WriteLine(t.Name);
                                myContext.Db.CodeFirst.SplitTables().InitTables(t);
                            }
                        });
                        ConsoleHelper.WriteSuccessLine($"Tables created successfully!");
                        Console.WriteLine();
                    }

                    //初始化数据
                    if (AppSettings.app(new string[] { "AppSettings", "SeedDBDataEnabled" }).ObjToBool())
                    {
                        ConsoleHelper.WriteInfoLine("初始化数据库基础数据...");

                        JsonSerializerSettings setting = new JsonSerializerSettings();
                        JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
                        {
                            //日期类型默认格式化处理
                            setting.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
                            setting.DateFormatString = "yyyy-MM-dd HH:mm:ss";

                            //空值处理
                            setting.NullValueHandling = NullValueHandling.Ignore;

                            //高级用法九中的Bool类型转换 设置
                            //setting.Converters.Add(new BoolConvert("是,否"));

                            return setting;
                        });

                        #region Role

                        if (!await myContext.Db.Queryable<Role>().AnyAsync())
                        {
                            var data = JsonConvert.DeserializeObject<List<Role>>(
                                FileHelper.ReadFile(string.Format(SeedDataFolder, "Role"), Encoding.UTF8), setting);
                            //using var stream = new FileStream(Path.Combine(WebRootPath, "BlogCore.Data.excel", "Role.xlsx"), FileMode.Open);
                            //var result = await importer.Import<Role>(stream);
                            //var data = result.Data.ToList();

                            myContext.GetEntityDB<Role>().InsertRange(data);
                            Console.WriteLine("Table:Role created success!");
                        }
                        else
                        {
                            Console.WriteLine("Table:Role already exists...");
                        }

                        #endregion

                        #region UserInfo

                        if (!await myContext.Db.Queryable<UserInfo>().AnyAsync())
                        {
                            var data = JsonConvert.DeserializeObject<List<UserInfo>>(
                                FileHelper.ReadFile(string.Format(SeedDataFolder, "UserInfo"), Encoding.UTF8), setting);
                            //using var stream = new FileStream(Path.Combine(WebRootPath, "BlogCore.Data.excel", "Role.xlsx"), FileMode.Open);
                            //var result = await importer.Import<Role>(stream);
                            //var data = result.Data.ToList();

                            myContext.GetEntityDB<UserInfo>().InsertRange(data);
                            Console.WriteLine("Table:UserInfo created success!");
                        }
                        else
                        {
                            Console.WriteLine("Table:UserInfo already exists...");
                        }

                        #endregion

                        ConsoleHelper.WriteSuccessLine($"Done seeding database!");
                    }
                }
                Console.WriteLine();
            }
            catch (Exception ex)
            {
                ConsoleHelper.WriteErrorLine(
                    $"加载数据失败：" + ex.Message);
                throw new Exception(
                    $"加载数据失败：" + ex.Message);
            }
        }
    }
}
